package com.hb.trade.server.center.au.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hb.core.pojo.center.au.dto.RoleDTO;
import com.hb.core.pojo.center.au.dto.UserDTO;
import com.hb.core.pojo.center.au.entity.Role;
import com.hb.core.pojo.center.au.entity.User;
import com.hb.core.pojo.center.au.entity.UserRole;
import com.hb.core.pojo.center.au.mapper.UserRoleMapper;
import com.hb.core.pojo.enums.RoleSignEnum;
import com.hb.core.pojo.enums.RoleTypeEnum;
import com.hb.core.pojo.parent.MPCommonEntity;
import com.hb.trade.server.center.au.service.RoleService;
import com.hb.trade.server.center.au.service.UserRoleService;
import com.hb.trade.server.center.au.service.UserService;
import org.bouncycastle.math.ec.custom.sec.SecT113Field;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;

/**
 * 角色关联中间表, 用于关联用户角色 服务实现类
 *
 * @author zhaojk
 * @since 2021-11-29
 */
@Service
public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRole> implements UserRoleService {

    protected final RoleService roleService;
    protected final UserService userService;

    public UserRoleServiceImpl(RoleService roleService,
                               UserService userService) {
        this.roleService = roleService;
        this.userService = userService;
    }

    /**
     * 给用户赋予指定的业务角色
     * 该方法将赋予指定角色的总公司管理员
     * 该方法会验证该userId是否为一级帐号, 只有一级帐号才能赋予总公司管理员角色
     *
     * @param userId   需要被赋予角色的用户ID
     * @param roleSign 业务角色只能是枚举中的一个
     * @return
     * @see com.hb.core.pojo.enums.RoleSignEnum
     */
    @Override
    public boolean grantRole(Long userId, RoleSignEnum... roleSign) {
        if (userId == null) {
            return false;
        }
        if (ArrayUtil.isEmpty(roleSign)) {
            return false;
        }
        User orgUser = userService.getById(userId);
        Integer accountLevel = orgUser.getAccountLevel();
        if (accountLevel > 1) {
            return false;
        }

        List<UserRole> userRoles = CollUtil.list(false);
        for (RoleSignEnum roleSignEnum : roleSign) {
            Role role = roleService.getRoleByRoleSign(roleSignEnum);
            if (role == null) {
                return false;
            }
            UserRole userRole = new UserRole();
            userRole.setUserId(userId);
            userRole.setRoleId(role.getId());

            // 查询是否已经存在该权限
            QueryWrapper<UserRole> buildWrapper = userRole.buildWrapper();
            long count = count(buildWrapper);
            if (count > 0) {
                continue;
            }
            userRole.buildBaseData(1);
            userRoles.add(userRole);
        }
        if (CollUtil.size(userRoles) > 0) {
            return saveBatch(userRoles);
        }
        return false;
    }

    /**
     * 更新用户角色
     *
     * @param user#id
     * @param user#roleIds
     * @return
     */
    @Transactional
    @Override
    public boolean updateUserRoles(UserDTO user) {
        // 删除原有用户角色
        QueryWrapper<UserRole> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", user.getId());
        remove(wrapper);

        // 添加新的角色
        Set<Long> roleIds = user.getRoleIds();
        if (CollUtil.isEmpty(roleIds)) {
            return true;
        }

        List<UserRole> userRoleList = CollUtil.list(false);

        for (Long roleId : roleIds) {
            UserRole userRole = new UserRole();
            userRole.setUserId(user.getId());
            userRole.setRoleId(roleId);
            userRole.buildBaseData(1);
            userRoleList.add(userRole);
        }
        return saveBatch(userRoleList);
    }

    /**
     * 获取指定用户的角色
     *
     * @param userId
     * @return
     */
    @Override
    public List<RoleDTO> listRolesByUserId(Long userId) {
        if (userId == null) {
            return CollUtil.list(false);
        }

        QueryWrapper<UserRole> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId);

        List<UserRole> userRoles = list(wrapper);
        List<Long> roleIds = CollUtil.map(userRoles, UserRole::getRoleId, true);

        if (CollUtil.isEmpty(roleIds)) {
            return CollUtil.list(false);
        }

        QueryWrapper<Role> wrapperRole = Role.wrapper("id", "role_name", "role_code", "role_sign", "role_data_auth", "role_type");
        wrapperRole.in("id", roleIds);
        List<Role> roles = roleService.list(wrapperRole);
        return MPCommonEntity.to(roles, RoleDTO.class);
    }

    /**
     * 查询指定用户列表的招投标角色
     *
     * @param userIds
     * @return
     */
    @Override
    public List<RoleDTO> listBiddingRolesByUserIds(List<Long> userIds) {
        if (CollUtil.isEmpty(userIds)) {
            return CollUtil.list(false);
        }

        boolean containsAdmin = containsAdmin(userIds);
        return baseMapper.listBiddingRolesByUserIds(userIds, containsAdmin);
    }

    /**
     * 判断用户ID列表中是否包含超级管理员
     *
     * @param userIds
     * @return
     */
    @Override
    public boolean containsAdmin(List<Long> userIds) {
        QueryWrapper<User> wrapper = User.wrapper();
        wrapper.eq("user_type", 1).in("id", userIds);
        return userService.count(wrapper) > 0;
    }

    /**
     * 给指定的用户添加企业管理员角色
     *
     * @param userId
     * @return
     */
    @Override
    public boolean grantOrgManager(Long userId) {
        if (userId == null) {
            return false;
        }
        QueryWrapper<UserRole> wrapper = UserRole.wrapper();
        wrapper.eq("user_id", userId).eq("role_id", 1518146685950865408L);
        long count = count(wrapper);
        if (count > 0) {
            return true;
        }

        UserRole userRole = new UserRole();
        // 数据库中的企业管理员角色
        userRole.setRoleId(1518146685950865408L);
        userRole.setUserId(userId);
        userRole.buildBaseData(1);
        return saveOrUpdate(userRole);
    }

    /**
     * 给指定的用户添加未审核的代理机构角色
     *
     * @param userId
     * @return
     */
    @Override
    public boolean grantUnCheckedAgency(Long userId) {
        if (userId == null) {
            return false;
        }
        QueryWrapper<UserRole> wrapper = UserRole.wrapper();
        wrapper.eq("user_id", userId).eq("role_id", 1506899590577774592L);
        long count = count(wrapper);
        if (count > 0) {
            return true;
        }

        UserRole userRole = new UserRole();
        // 数据库中的企业管理员角色
        userRole.setRoleId(1506899590577774592L);
        userRole.setUserId(userId);
        userRole.buildBaseData(1);
        return saveOrUpdate(userRole);
    }

    @Override
    public boolean deleteRole(Long userId, RoleTypeEnum roleTypeEnum) {
        Role role = roleService.getRoleByRoleType(roleTypeEnum);
        if (role == null) {
            return true;
        }
        // 删除原有用户角色
        QueryWrapper<UserRole> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId).eq("role_id", role.getId());
        return remove(wrapper);
    }

    /**
     * 查询指定角色下的用户列表
     *
     * @param roleId
     * @return
     */
    @Override
    public List<UserDTO> listMembersByRoleId(Long roleId) {
        return baseMapper.listMembersByRoleId(roleId);
    }
}
